[CSS] 검색창 클릭시 아이콘 포함 테두리 생기기

리액트로 아마존 클론을 하고 있다. 헤더부분 검색창 클릭을 하면 주황 테두리가 이쁘게 딱 생기는데 의외로 쉽지 않아서 기록해본다.

마크업

<div className="header__search">
  <select className="header__searchSelect">
    {' '}
    {/* All */}
    <option value="All">All</option>
    <option value="arts-craft">Arts & Craft</option>
    <option value="automotive">automotive</option>
    <option value="baby">baby</option>
  </select>
  <input type="text" className="header__searchInput" /> {/* input */}
  <SearchIcon className="header__searchIcon" /> {/* 돋보기아이콘 */}
</div>

참고로 돋보기 아이콘을 위한 <SearchIcon>태그는 material-ui.com 사이트를 이용했다. npm 으로 다운받고 npm install @material-ui/core npm install @material-ui/icons

이렇게 임포트 해준다음에 사용하면 된다.

import SearchIcon from '@material-ui/icons/Search'

border vs outline

input태그에 focus를 하면 자동으로 outline이 생긴다. 일단 이것부터 지워준다.

.header__searchInput:focus {
  outline: none;
}

border를 주면 레이아웃에 영향을 주어 모양이 이상해진다. 그래서 outline 을 사용하면 좋다. 그치만 outline-radius 가 없기 때문에 radius를 주기 위해서는 다른 방법을 써야 한다. 밑에 설명!

outline 에 radius 주기

다른말로 하면 border-radius 를 사용하면서 레이아웃이 깨지지 않게 하기 pseudo-element 를 사용해서 테두리를 만들어준다.

.header__search:focus::before {
  content: '';
  display: block;
  position: absolute;
  top: -1px;
  bottom: -1px;
  left: -1px;
  right: -1px;
  border: 2px solid orange;
  border-radius: 3px;
}

-1px를 상하좌우에 줬는데 이렇게 해야 테두리가 바깥에 생긴다.

focus-within

input:focus 일 때 전체 div 에 테두리 주기. focus-within 사용해야 input, 즉 적용하려는 div 의 안쪽을 클릭해도 focus 인식이 된다.

전체코드

.header__search:focus-within::before {
  content: '';
  display: block;
  position: absolute;
  top: -1px;
  bottom: -1px;
  left: -1px;
  right: -1px;
  border: 2px solid orange;
  border-radius: 3px;
}

Written by@Jiyon Lee
뜨거운 코드를 가르며

GitHub